package features;

import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.noear.solon.annotation.Inject;
import org.noear.solon.data.annotation.TranAnno;
import org.noear.solon.data.sql.SqlUtils;
import org.noear.solon.data.tran.TranUtils;
import org.noear.solon.test.SolonTest;
import com.xlongwei.accounts.App;
import com.xlongwei.accounts.model.User;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@SolonTest(App.class)
public class SqlTest {
    @Inject
    SqlUtils sqlUtils;

    @Test
    public void select1() throws Exception {
        Number tmp = sqlUtils.sql("select 1").queryValue();
        System.out.println(tmp);
        assert "1".equals(tmp.toString());
    }

    @Test
    public void selectAll() throws Exception {
        List<String> tables =
                Arrays.asList("t_user,t_ledger,t_account,t_member,t_record,t_extra".split("[,]"));
        for (String table : tables) {
            log.info("{}: {}", table,
                    (Long) sqlUtils.sql("select count(1) from " + table).queryValue());
        }
    }

    @Test
    public void insert1() throws Throwable {
        Assertions.assertThrows(Throwable.class, () -> {
            TranUtils.execute(new TranAnno(), () -> {
                Long rows = sqlUtils.sql("select count(1) from t_user").queryValue();
                System.out.println("rows=" + rows);
                sqlUtils.sql("insert into t_user(mobile,pass) values(?,?)", 15123011395L, "123456")
                        .update();
                List<User> list = sqlUtils.sql("select * from t_user").queryRowList(User.class);
                System.out.println("list=" + list);
                list.stream().forEach(System.out::println);
                log.info("list={}", list);
                Assertions.assertEquals(rows + 1, list.size());
                assert "123456".equals(list.listIterator().next().getPass());
                // 回滚数据
                throw new RuntimeException("rollback");
            });
        });
    }

    @FunctionalInterface
    public interface ThrowableRunner {
        void run() throws Throwable;
    }

    public static void testAndRollback(ThrowableRunner run) {
        Assertions.assertThrows(Throwable.class, () -> {
            TranUtils.execute(new TranAnno(), () -> {
                try {
                    run.run();
                    System.err.println("success");
                } catch (Throwable t) {
                    t.printStackTrace();
                }
                System.err.println("rollback");
                throw new RuntimeException("rollback");
            });
        });
    }
}
